/********************************************
 * 功能说明: 
 * 模块名称: 
 * 系统名称: 
 * 软件版权: 
 * 系统版本: 1.0.0
 * 开发人员: Frank
 * 开发时间: 2019/12/3 23:02
 * 审核人员: 
 * 相关文档: 
 * 修改记录: 修改日期 修改人员 修改说明
 *********************************************/
package com.spring.arch.uaa.store;

import com.hazelcast.core.MapStoreAdapter;
import com.spring.arch.uaa.enums.AuthorityType;
import com.spring.arch.uaa.enums.AuthorityType;
import com.spring.arch.uaa.model.Authority;
import com.spring.arch.uaa.model.RoleAuthority;
import com.spring.arch.uaa.oauth2.dynamic.UrlPattern;
import com.spring.arch.uaa.repository.AuthorityRepository;
import com.spring.arch.uaa.repository.RoleAuthorityRepository;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.http.HttpMethod;
import org.springframework.security.access.ConfigAttribute;
import org.springframework.security.access.SecurityConfig;
import org.springframework.stereotype.Component;
import org.springframework.transaction.annotation.Transactional;
import org.springframework.util.AntPathMatcher;
import org.springframework.util.CollectionUtils;

import java.util.ArrayList;
import java.util.Collection;
import java.util.List;

/**
 * url - roles load store
 *
 * @author Frank
 * @version 1.0.0.1
 * @since 2019/12/3 23:02
 */
@Slf4j
@Component
@Transactional(rollbackFor = Exception.class)
public class UrlRoleStore extends MapStoreAdapter<UrlPattern, Collection<ConfigAttribute>> {

    @Autowired
    private AuthorityRepository resourceRepository;
    @Autowired
    private RoleAuthorityRepository roleAuthorityRepository;

    @Override
    public Collection<ConfigAttribute> load(UrlPattern urlPattern) {
        final String url = urlPattern.getUrl();
        final HttpMethod method = urlPattern.getMethod();
        List<ConfigAttribute> res = new ArrayList<>();
        List<Authority> resources = resourceRepository.findByHttpMethodAndTypeAndDisableFalse(method, AuthorityType.URL);
        if (!CollectionUtils.isEmpty(resources)) {
            resources.stream().filter(resource -> new AntPathMatcher().match(resource.getUrl(), url)).findFirst().ifPresent(resource -> {
                final List<RoleAuthority> roleAuthorities = roleAuthorityRepository.findByAuthority(resource);
                if (!CollectionUtils.isEmpty(roleAuthorities)) {
                    roleAuthorities.forEach(rr -> {
                        SecurityConfig config = new SecurityConfig(rr.getRole().getCode());
                        res.add(config);
                    });
                }
            });
        }
        return res;
    }
}
